﻿using System.Collections.Generic;
using System.Data.Services.Client;
using System.Threading;
using BookStoreService.Core.Models;
using BookStoreService.Host;
using BookStoreService.Tests.Tools;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Linq;

namespace BookStoreService.Tests
{
    [TestClass]
    public class FunctionalTests
    {
        private static TestService s_service;
        private DataServiceContext serviceContext;

        // Run once for all the tests
        [ClassInitialize()]
        public static void ClassInitialize(TestContext testContext)
        {
            // Start the DataService (Using WebServiceHost) 
            s_service = new TestService(typeof(BookStoreDataService));
        }

        [ClassCleanup]
        public static void ClassCleanup()
        {
            if (s_service != null)
            {
                s_service.Dispose();
                s_service = null;
            }
        }

        // Run before every test
        [TestInitialize]
        public void TestInitialize()
        {
            // Create the client data context
            serviceContext = new DataServiceContext(s_service.ServiceUri);
        }

        [TestMethod]
        public void QueryForBooks()
        {
            testContextInstance.BeginTimer("Read Books");
            DataServiceQuery<Book> booksQuery = serviceContext.CreateQuery<Book>("Books");
            List<Book> Books = booksQuery.ToList();
            testContextInstance.EndTimer("Read Books");
            
            Assert.AreEqual(2, Books.Count, "Books number is wrong");

            Book book = Books[0];
            Assert.AreEqual("Book1", book.Name, "Book name is wrong");

            book = Books[1];
            Assert.AreEqual("Book2", book.Name, "Book name is wrong");
        }

        [TestMethod]
        public void QueryForAuthors()
        {
            testContextInstance.BeginTimer("Read Authors");
            List<Author> tables = serviceContext.CreateQuery<Author>("Authors").ToList();
            Assert.AreEqual(3, tables.Count, "Authors number is wrong");
            testContextInstance.EndTimer("Read Authors");
        }

        [TestMethod]
        public void UpdateBook()
        {
            List<Book> Books = serviceContext.CreateQuery<Book>("Books").ToList();
            Assert.AreEqual(2, Books.Count, "Books number is wrong");

            Book book = Books[0];
            Assert.AreEqual("Book1", book.Name, "Book name is wrong");

            const string description = "New description";

            book.Description = description;

            testContextInstance.BeginTimer("Update Book");
            serviceContext.UpdateObject(book);
            // Synchronous save
            serviceContext.SaveChanges(SaveChangesOptions.None);
            testContextInstance.EndTimer("Update Book");

            serviceContext = new DataServiceContext(s_service.ServiceUri);

            Books = serviceContext.CreateQuery<Book>("Books").ToList();
            book = Books[0];
            Assert.AreEqual(book.Description, description, "Update description failed");
        }

        #region TestContext

        private TestContext testContextInstance;
        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #endregion
    }
}
